package middleware

import (
	"fmt"
	"WchimeGinSystem/conf"
	"WchimeGinSystem/utils"
	"WchimeGinSystem/utils/cache"
	"WchimeGinSystem/utils/errmsg"
	jwtauth "WchimeGinSystem/utils/jwtAuth"
	"strings"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis/v8"
)

func JWTAuth() gin.HandlerFunc {
	return func(ctx *gin.Context) {
		tokenHeader := ctx.Request.Header.Get("Authorization")
		if tokenHeader == "" {
			utils.RespContext(ctx).ErrorResp(nil, errmsg.ERROR_TOKEN_VALID, "")
			ctx.Abort()
			return
		}

		checkToken := strings.Split(tokenHeader, " ")

		if len(checkToken) != 2 || checkToken[0] != "Bearer" {
			utils.RespContext(ctx).ErrorResp(nil, errmsg.ERROR_TOKEN_VALID, "")
			ctx.Abort()
			return
		}

		claims, err := jwtauth.ParserToken(checkToken[1])
		if err != nil {
			utils.RespContext(ctx).ErrorResp(nil, errmsg.ERROR_TOKEN_VALID, "")
			ctx.Abort()
			return
		}

		login_k := fmt.Sprintf("%s_%s", conf.SERVER_NAME, string(claims.UserId))
		val, err := cache.RDB.Get(cache.CTX, login_k).Result()
		if val != checkToken[1] {
			utils.RespContext(ctx).ErrorResp(nil, errmsg.ERROR_TOKEN_VALID, "")
			ctx.Abort()
			return
		}

		if err == redis.Nil {
			utils.RespContext(ctx).ErrorResp(nil, errmsg.ERROR_TOKEN_VALID, "")
			ctx.Abort()
			return
		} else if err != nil {
			utils.RespContext(ctx).ErrorResp(nil, errmsg.ERROR_BASE, "")
			ctx.Abort()
			return
		}

		err = cache.RDB.Set(cache.CTX, login_k, checkToken[1], 7200*time.Second).Err()
		if err != nil {
			utils.RespContext(ctx).ErrorResp(nil, errmsg.ERROR_BASE, "")
			return
		}

		ctx.Set("user", claims)

		ctx.Next()
	}
}
